package oms.dao;

import java.util.List;

import oms.entities.User;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class UserDAOImpl implements UserDAO {
	
	@Autowired
	private SessionFactory sessionFactory; 

	@Override
	public void createUser(User user) {
		
		 sessionFactory.getCurrentSession().save(user);
	}

	@Override
	public void updateUser(User user) {
		
		 sessionFactory.getCurrentSession().update(user);
	}

	@Override
	public void deleteUser(Long userId) {
		
		 sessionFactory.getCurrentSession().delete(getUserById(userId));

	}

	@Override
	public User getUserById(Long userId) {
			
		 return (User) sessionFactory.getCurrentSession().get(User.class, userId);
	}

	@Override
	public List<User> getAllUsers(int index, int size) {
		
		Session session = sessionFactory.getCurrentSession();
		Criteria criteria = session.createCriteria(User.class).addOrder(Order.asc("userId") );
		criteria.setFirstResult((index - 1) * size);
		criteria.setMaxResults(size);
		
		@SuppressWarnings("unchecked")
		List<User> users = (List<User>) criteria.list();
		if (users!=null && users.size()!=0) {
			System.out.println("Total Results:" + users.size());
			for (User user : users) {
				System.out.println(user.getUserId() + " - " + user.getFirstName());
			}
		 }
		 
		 return users;
	}

	@Override
	public List<User> findUser(String field, String value, String match, int index, int size) {
		
		 Session session = sessionFactory.getCurrentSession();
		 List<User> list;
		 Criteria criteria = session.createCriteria(User.class);
		 criteria.setFirstResult((index - 1) * size);
		 criteria.setMaxResults(size);
		 if(field.equals("all")) {
			 field="login";
		 }
		 if(field.equals("role")) {
			 field="login";
		 }
		 
		 if(match.equals("ne")) {
			
			 			criteria.add( Restrictions.ne(field, value));
					    
		 } else
		 
		 if(match.equals("nl")) {
			 
			criteria.add( Restrictions.not(Restrictions.like(field, value, MatchMode.ANYWHERE)));
					    
		 } else {
		 MatchMode mode;
		 if(match.equals("start")) {
			 mode=MatchMode.START;
		 } else if (match.equals("end")) {
			 mode=MatchMode.END;
		 } else if(match.equals("anywhere")) {
			 mode=MatchMode.ANYWHERE;
		 } else {
			 mode=MatchMode.EXACT;
		 }
		 
		 
		 criteria.add( Restrictions.like(field, value, mode));
				 
		 }
		 
		return (List<User>)criteria.list();
	 }

	@Override
	public User getUserByLogin(String userLogin) {
		Session session = sessionFactory.getCurrentSession();
		Criteria criteria = session.createCriteria(User.class).add(
				Restrictions.eq("login", userLogin)
				);
		List<User> users = (List<User>) criteria.list();

		if(users!=null && users.size()!=0) {
			return users.get(0);
		}
		return null;
	}

	@Override
	public User getUserByMail(String userMail) {
		Session session = sessionFactory.getCurrentSession();
		Criteria criteria = session.createCriteria(User.class).add(
				Restrictions.eq("mail", userMail)
				);
		List<User> users = (List<User>) criteria.list();

		if(users!=null && users.size()!=0) {
			return users.get(0);
		}
		return null;
	}

	@Override
	@Transactional
	public Integer getCount() {
		
		Session session = sessionFactory.getCurrentSession();
		return (Integer) session.createCriteria(User.class).setProjection(Projections.rowCount()).uniqueResult();
	}
	
}